package icasue.reflect.handles.map;

import lombok.SneakyThrows;
import icasue.reflect.handles.OAble;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Map;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2020/11/30 上午11:42
 * @UpdateDate:
 * @Description:
 */
public class MapO implements OAble {

    static {
        try {
            Class<?> loadHandleOperate = MapO.class.getClassLoader().loadClass("icasue.reflect.handles.HandleSupplier");
            MapO.lookup = (MethodHandles.Lookup)loadHandleOperate.getDeclaredField("methodLookup").get(null);
        }catch (Throwable e){
            /**/
        }
    }

    static {
        findMapOperator();
    }

    public static MethodHandles.Lookup lookup;

    /**
     * 常用操作
     */
    public static MethodHandle clear;
    public static MethodHandle putAll;
    public static MethodHandle put;
    public static MethodHandle putIfAbsent;
    public static MethodHandle get;
    public static MethodHandle getOrDefault;
    public static MethodHandle remove;
    public static MethodHandle size;


    @SneakyThrows(value = Throwable.class)
    public static void findMapOperator(){
        clear = lookup.findVirtual(Map.class, "clear", MethodType.methodType(void.class));
        putAll = lookup.findVirtual(Map.class, "putAll", MethodType.methodType(void.class,Map.class));
        put = lookup.findVirtual(Map.class, "put", MethodType.methodType(Object.class,Object.class,Object.class));
        get = lookup.findVirtual(Map.class, "get", MethodType.methodType(Object.class,Object.class));
        getOrDefault = lookup.findVirtual(Map.class, "getOrDefault", MethodType.methodType(Object.class,Object.class,Object.class));
        remove = lookup.findVirtual(Map.class, "remove", MethodType.methodType(Object.class,Object.class));
        size = lookup.findVirtual(Map.class, "size", MethodType.methodType(int.class));
        putIfAbsent = lookup.findVirtual(Map.class, "putIfAbsent", MethodType.methodType(Object.class,Object.class,Object.class));
    }
}
